#include "global.h"
#include "paths.h"
#include "staticfunctions.h"
#include "propertyeditor.h"

int Paths::count() { return m_paths.count(); }

Paths::Paths()
{
  m_sameForAll = true;
  m_paths.clear();
}

Paths::~Paths()
{
  clear();
}
void 
Paths::clear()
{
  for(int i=0; i<m_paths.count(); i++)
    m_paths[i]->disconnect();

  for(int i=0; i<m_paths.count(); i++)
    m_paths[i]->removeFromMouseGrabberPool();

  for(int i=0; i<m_paths.count(); i++)
    delete m_paths[i];

  m_paths.clear();
}

bool
Paths::isInMouseGrabberPool(int i)
{
  if (i < m_paths.count())
    return m_paths[i]->isInMouseGrabberPool();
  else
    return false;
}
void
Paths::addInMouseGrabberPool(int i)
{
  if (i < m_paths.count())
    m_paths[i]->addInMouseGrabberPool();
}
void
Paths::addInMouseGrabberPool()
{
  for(int i=0; i<m_paths.count(); i++)
    m_paths[i]->addInMouseGrabberPool();
}
void
Paths::removeFromMouseGrabberPool(int i)
{
  if (i < m_paths.count())
    m_paths[i]->removeFromMouseGrabberPool();
}

void
Paths::removeFromMouseGrabberPool()
{
  for(int i=0; i<m_paths.count(); i++)
    m_paths[i]->removeFromMouseGrabberPool();
}


bool
Paths::grabsMouse()
{
  for(int i=0; i<m_paths.count(); i++)
    {
      if (m_paths[i]->grabsMouse())
	return true;
    }
  return false;
}


void
Paths::addPath(QList<Vec> pts)
{
  PathGrabber *pg = new PathGrabber();
  pg->setPoints(pts);
  m_paths.append(pg);

  makePathConnections();
}

void
Paths::addPath(PathObject po)
{
  PathGrabber *pg = new PathGrabber();
  pg->set(po);
  m_paths.append(pg);

  makePathConnections();
}

void
Paths::addPath(QString flnm)
{
  QList<Vec> pts;
  QFile fpath(flnm);
  fpath.open(QFile::ReadOnly);
  QTextStream fd(&fpath);
  while (! fd.atEnd())
    {
      QString line = fd.readLine();
      QStringList list = line.split(" ", QString::SkipEmptyParts);
      if (list.count() == 1)
	{
	  int npts = list[0].toInt();
	  for(int i=0; i<npts; i++)
	    {
	      if (fd.atEnd())
		break;
	      else
		{
		  QString line = fd.readLine();
		  QStringList list = line.split(" ", QString::SkipEmptyParts);
		  if (list.count() == 3)
		    {
		      float x = list[0].toFloat();
		      float y = list[1].toFloat();
		      float z = list[2].toFloat();
		      pts.append(Vec(x,y,z));
		    }
		}
	    }
	  break;
	}
    }

  if (pts.count() > 0)
    {
      PathGrabber *pg = new PathGrabber();
      pg->setPoints(pts);
      m_paths.append(pg);

      makePathConnections();
    }
}

QList<PathObject>
Paths::paths()
{
  QList<PathObject> po;
  for(int i=0; i<m_paths.count(); i++)
    po.append(m_paths[i]->get());

  return po;
}

void
Paths::setPaths(QList<PathObject> po)
{
  clear();

  for(int i=0; i<po.count(); i++)
    {
      PathGrabber *pg = new PathGrabber();
      pg->set(po[i]);
      m_paths.append(pg);
    }

  makePathConnections();
}

void
Paths::updateScaling()
{
  for(int i=0; i<m_paths.count();i++)
    m_paths[i]->computePathLength();
}

void
Paths::draw(QGLViewer *viewer, bool backToFront, Vec lightVec)
{
  for(int i=0; i<m_paths.count();i++)
    m_paths[i]->draw(viewer,
		     m_paths[i]->grabsMouse(),
		     backToFront,
		     lightVec);
}

void
Paths::postdraw(QGLViewer *viewer)
{
  for(int i=0; i<m_paths.count();i++)
    {
      int x,y;
      m_paths[i]->mousePosition(x,y);
      m_paths[i]->postdraw(viewer,
			   x, y,
			   m_paths[i]->grabsMouse());
    }
}

bool
Paths::keyPressEvent(QKeyEvent *event)
{
  for(int i=0; i<m_paths.count(); i++)
    {
      if (m_paths[i]->grabsMouse())
	{
	  if (event->key() == Qt::Key_C)
	    {
	      bool b = m_paths[i]->closed();
	      m_paths[i]->setClosed(!b);
	      return true;
	    }
	  else if (event->key() == Qt::Key_P)
	    {
	      bool b = m_paths[i]->showPoints();
	      m_paths[i]->setShowPoints(!b);    
	      return true;
	    }
	  else if (event->key() == Qt::Key_N)
	    {
	      bool b = m_paths[i]->showPointNumbers();
	      m_paths[i]->setShowPointNumbers(!b);    
	      return true;
	    }
	  else if (event->key() == Qt::Key_L)
	    {
	      if (event->modifiers() & Qt::ShiftModifier)
		{
		  m_paths[i]->setCaptionLabel(!m_paths[i]->captionLabel());
		}
	      else
		{
		  bool b = m_paths[i]->showLength();
		  m_paths[i]->setShowLength(!b);    
		}
	      return true;
	    }
	  else if (event->key() == Qt::Key_X)
	    {
	      m_paths[i]->setMoveAxis(PathGrabber::MoveX);
	      return true;
	    }
	  else if (event->key() == Qt::Key_Y)
	    {
	      if (event->modifiers() & Qt::ControlModifier)
		m_paths[i]->redo();
	      else
		m_paths[i]->setMoveAxis(PathGrabber::MoveY);
	      return true;
	    }
	  else if (event->key() == Qt::Key_Z)
	    {
	      if (event->modifiers() & Qt::ControlModifier)
		m_paths[i]->undo();
	      else
		m_paths[i]->setMoveAxis(PathGrabber::MoveZ);
	      return true;
	    }
	  else if (event->key() == Qt::Key_W)
	    {
	      m_paths[i]->setMoveAxis(PathGrabber::MoveAll);
	      return true;
	    }
	  else if (event->key() == Qt::Key_S)
	    {
	      int idx = m_paths[i]->pointPressed();
	      if (idx > -1)
		{
		  float radx = m_paths[i]->getRadX(idx);
		  if (event->modifiers() & Qt::ShiftModifier)
		    radx--;
		  else
		    radx++;
		  radx = qMax(1.0f, radx);
		  m_paths[i]->setRadX(idx, radx, m_sameForAll);
		  return true;
		}
	    }
	  else if (event->key() == Qt::Key_T)
	    {
	      int idx = m_paths[i]->pointPressed();
	      if (idx > -1)
		{
		  float rady = m_paths[i]->getRadY(idx);
		  if (event->modifiers() & Qt::ShiftModifier)
		    rady--;
		  else
		    rady++;
		  rady = qMax(1.0f, rady);
		  m_paths[i]->setRadY(idx, rady, m_sameForAll);
		}
	      else // switch to tube mode
		{
		  if (!(event->modifiers() & Qt::ShiftModifier))
		    {
		      bool b = m_paths[i]->tube();
		      m_paths[i]->setTube(!b);
		    }
		  else
		    m_paths[i]->loadCaption();
		}

	      return true;
	    }
	  else if (event->key() == Qt::Key_A)
	    {
	      int idx = m_paths[i]->pointPressed();
	      if (idx > -1)
		{
		  float a = m_paths[i]->getAngle(idx);
		  if (event->modifiers() & Qt::ShiftModifier)
		    a--;
		  else
		    a++;
		  m_paths[i]->setAngle(idx, a, m_sameForAll);
		  return true;
		}
	      else
		{
		  bool b = m_paths[i]->showAngle();
		  m_paths[i]->setShowAngle(!b);    
		  return true;
		}
		
	    }
	  else if (event->key() == Qt::Key_Delete)
	    {
	      m_paths[i]->removeFromMouseGrabberPool();
	      m_paths.removeAt(i);
	      return true;
	    }
	  
	  if (event->key() == Qt::Key_Space)
	    {
	      if (m_paths[i]->captionGrabbed())
		{
		  m_paths[i]->loadCaption();
		  return true;
		}

	      PropertyEditor propertyEditor;
	      QMap<QString, QVariantList> plist;

	      QVariantList vlist;

	      vlist.clear();
	      vlist << QVariant("double");
	      vlist << QVariant(m_paths[i]->opacity());
	      vlist << QVariant(0.0);
	      vlist << QVariant(1.0);
	      vlist << QVariant(0.1); // singlestep
	      vlist << QVariant(1); // decimals
	      plist["opacity"] = vlist;

	      vlist.clear();
	      vlist << QVariant("color");
	      Vec pcolor = m_paths[i]->color();
	      QColor dcolor = QColor::fromRgbF(pcolor.x,
					       pcolor.y,
					       pcolor.z);
	      vlist << dcolor;
	      plist["color"] = vlist;

	      vlist.clear();
	      vlist << QVariant("int");
	      vlist << QVariant(m_paths[i]->segments());
	      vlist << QVariant(1);
	      vlist << QVariant(100);
	      plist["smoothness"] = vlist;

	      vlist.clear();
	      vlist << QVariant("int");
	      vlist << QVariant(m_paths[i]->sections());
	      vlist << QVariant(1);
	      vlist << QVariant(100);
	      plist["sections"] = vlist;

	      vlist.clear();
	      vlist << QVariant("checkbox");
	      vlist << QVariant(m_paths[i]->halfSection());
	      plist["half section"] = vlist;

	      vlist.clear();
	      vlist << QVariant("combobox");
	      vlist << QVariant(m_paths[i]->capType());
	      vlist << QVariant("flat");
	      vlist << QVariant("round");
	      vlist << QVariant("arrow");
	      plist["cap style"] = vlist;

	      vlist.clear();
	      vlist << QVariant("combobox");
	      vlist << QVariant(m_paths[i]->arrowDirection());
	      vlist << QVariant("forward");
	      vlist << QVariant("backward");
	      plist["arrow direction"] = vlist;

	      vlist.clear();
	      vlist << QVariant("double");
	      vlist << QVariant(m_paths[i]->arrowHeadLength());
	      vlist << QVariant(0.0);
	      vlist << QVariant(1000.0);
	      vlist << QVariant(1.0); // singlestep
	      vlist << QVariant(1); // decimals
	      plist["arrow length"] = vlist;

	      vlist.clear();
	      vlist << QVariant("checkbox");
	      vlist << QVariant(m_paths[i]->arrowForAll());
	      plist["arrows for all"] = vlist;

	      vlist.clear();
	      vlist << QVariant("checkbox");
	      vlist << QVariant(m_sameForAll);
	      plist["same for all"] = vlist;

	      vlist.clear();
	      vlist << QVariant("checkbox");
	      vlist << QVariant(m_paths[i]->showAngle());
	      plist["display angle"] = vlist;

	      vlist.clear();
	      vlist << QVariant("checkbox");
	      vlist << QVariant(m_paths[i]->showLength());
	      plist["display path length"] = vlist;

	      vlist.clear();
	      vlist << QVariant("color");
	      pcolor = m_paths[i]->lengthColor();
	      dcolor = QColor::fromRgbF(pcolor.x,
					pcolor.y,
					pcolor.z);
	      vlist << dcolor;
	      plist["text color"] = vlist;

	      vlist.clear();
	      vlist << QVariant("int");
	      vlist << QVariant(m_paths[i]->lengthTextDistance());
	      vlist << QVariant(-1000);
	      vlist << QVariant(1000);
	      plist["length text distance"] = vlist;

	      vlist.clear();
	      plist["command"] = vlist;


	      vlist.clear();
	      QFile helpFile(":/paths.help");
	      if (helpFile.open(QFile::ReadOnly))
		{
		  QTextStream in(&helpFile);
		  QString line = in.readLine();
		  while (!line.isNull())
		    {
		      if (line == "#begin")
			{
			  QString keyword = in.readLine();
			  QString helptext;
			  line = in.readLine();
			  while (!line.isNull())
			    {
			      helptext += line;
			      helptext += "\n";
			      line = in.readLine();
			      if (line == "#end") break;
			    }
			  vlist << keyword << helptext;
			}
		      line = in.readLine();
		    }
		}	      
	      plist["commandhelp"] = vlist;

	      QStringList keys;
	      keys << "color";
	      keys << "opacity";
	      keys << "gap";
	      keys << "smoothness";
	      keys << "sections";
	      keys << "half section";
	      keys << "gap";
	      keys << "cap style";
	      keys << "arrow direction";
	      keys << "arrows for all";
	      keys << "arrow length";
	      keys << "gap";
	      keys << "display angle";
	      keys << "display path length";
	      keys << "text color";
	      keys << "length text distance";
	      keys << "gap";
	      keys << "same for all";
	      keys << "command";
	      keys << "commandhelp";
	      

	      propertyEditor.set("Path Parameters", plist, keys);

	      
	      QMap<QString, QPair<QVariant, bool> > vmap;

	      if (propertyEditor.exec() == QDialog::Accepted)
		vmap = propertyEditor.get();
	      else
		return true;
	      
	      keys = vmap.keys();

	      for(int ik=0; ik<keys.count(); ik++)
		{
		  QPair<QVariant, bool> pair = vmap.value(keys[ik]);


		  if (pair.second)
		    {
		      if (keys[ik] == "color")
			{
			  QColor color = pair.first.value<QColor>();
			  float r = color.redF();
			  float g = color.greenF();
			  float b = color.blueF();
			  pcolor = Vec(r,g,b);
			  m_paths[i]->setColor(pcolor);
			}
		      else if (keys[ik] == "text color")
			{
			  QColor color = pair.first.value<QColor>();
			  float r = color.redF();
			  float g = color.greenF();
			  float b = color.blueF();
			  pcolor = Vec(r,g,b);
			  m_paths[i]->setLengthColor(pcolor);
			}
		      else if (keys[ik] == "opacity")
			m_paths[i]->setOpacity(pair.first.toDouble());
		      else if (keys[ik] == "sections")
			m_paths[i]->setSections(pair.first.toInt());
		      else if (keys[ik] == "smoothness")
			m_paths[i]->setSegments(pair.first.toInt());
		      else if (keys[ik] == "half section")
			m_paths[i]->setHalfSection(pair.first.toBool());
		      else if (keys[ik] == "cap style")
			m_paths[i]->setCapType(pair.first.toInt());
		      else if (keys[ik] == "arrow direction")
			m_paths[i]->setArrowDirection(pair.first.toInt());
		      else if (keys[ik] == "arrows for all")
			m_paths[i]->setArrowForAll(pair.first.toBool());
		      else if (keys[ik] == "arrow length")
			m_paths[i]->setArrowHeadLength(pair.first.toDouble());
		      else if (keys[ik] == "display path length")
			m_paths[i]->setShowLength(pair.first.toBool());
		      else if (keys[ik] == "display angle")
			m_paths[i]->setShowAngle(pair.first.toBool());
		      else if (keys[ik] == "length text distance")
			m_paths[i]->setLengthTextDistance(pair.first.toInt());
		      else if (keys[ik] == "same for all")
			{
			  m_sameForAll = pair.first.toBool();
			  m_paths[i]->setSameForAll(m_sameForAll);
			}
		    }
		}

	      QString cmd = propertyEditor.getCommandString();
	      if (!cmd.isEmpty())
		processCommand(i, cmd);	
	      
 	      updateGL();
	    }
	}
    }
  
  return true;
}

void
Paths::makePathConnections()
{
  for(int i=0; i<m_paths.count(); i++)
    m_paths[i]->disconnect();

  for(int i=0; i<m_paths.count(); i++)
    {
      connect(m_paths[i], SIGNAL(selectForEditing(int, int)),
	      this, SLOT(selectForEditing(int, int)));

      connect(m_paths[i], SIGNAL(deselectForEditing()),
	      this, SLOT(deselectForEditing()));
    }
}
void
Paths::deselectForEditing()
{
  for(int i=0; i<m_paths.count(); i++)
    m_paths[i]->setPointPressed(-1);
}

void
Paths::selectForEditing(int mouseButton,
			int p0)
{
  int idx = -1;
  for(int i=0; i<m_paths.count(); i++)
    {
      if (m_paths[i]->grabsMouse())
	{
	  idx = i;
	  break;
	}
    }
  if (idx == -1)
    return;

  if (mouseButton == Qt::RightButton)
    {
      if ((m_paths[idx]->points()).count() <= 2)
	emit showMessage("Sorry cannot remove current point. Must have atleast 2 points in a path", true);
      else if (m_paths[idx]->pointPressed() == -1)
	  emit showMessage("No point selected for removal", true);
      else
	m_paths[idx]->removePoint(m_paths[idx]->pointPressed());
    }
  else if (mouseButton == Qt::LeftButton && p0 > -1)
    m_paths[idx]->insertPointAfter(p0);
//  else
//    m_paths[idx]->setPointPressed(m_paths[idx]->pointPressed());
}

void
Paths::processCommand(int idx, QString cmd)
{
  bool ok;
  QString origCmd = cmd;
  cmd = cmd.toLower();
  QStringList list = cmd.split(" ", QString::SkipEmptyParts);
  
  int li = 0;
  while (li < list.count())
    {
      if (list[li] == "normalize" ||
	  list[li] == "normalise")
	{
	  m_paths[idx]->normalize();
	}
      else if (list[li] == "setradius" ||
	       list[li] == "radius" ||
	       list[li] == "height")
	{
	  if (list.count()-li > 1)
	    {
	      float rad = list[li+1].toFloat(&ok);
	      m_paths[idx]->setRadX(0, rad, true);
	      m_paths[idx]->setRadY(0, rad, true);
	      li++;
	    }
	  else
	    QMessageBox::information(0, "Path Command Error",
				     "No radius given");
	}
      else if (list[li] == "setrads" || list[li] == "rads")
	{
	  if (list.count()-li > 1)
	    {
	      float radx = list[li+1].toFloat(&ok);
	      m_paths[idx]->setRadX(0, radx, true);
	      li++;
	    }
	  else
	    QMessageBox::information(0, "Path Command Error",
				     "No S radius given");
	}
      else if (list[li] == "setradt" || list[li] == "radt")
	{
	  if (list.count()-li > 1)
	    {
	      float rady = list[li+1].toFloat(&ok);
	      m_paths[idx]->setRadY(0, rady, true);
	      li++;
	    }
	  else
	    QMessageBox::information(0, "Path Command Error",
				     "No T radius given");
	}
      else if (list[li] == "setangle" || list[li] == "angle")
	{
	  if (list.count()-li > 1)
	    {
	      float a = list[li+1].toFloat(&ok);
	      m_paths[idx]->setAngle(0, a, true);
	      li++;
	    }
	  else
	    QMessageBox::information(0, "Path Command Error",
				     "No angle given");
	}
      else if (list[li] == "showprofile")
	{
	  int radius = 0;
	  if (list.size()-li > 1)
	    {
	      radius = list[li+1].toInt(&ok);
	      radius = qMin(radius, (int)200);
	      li++;
	    }

	  int segments = m_paths[idx]->segments();
	  QList<Vec> pathPoints = m_paths[idx]->getPointPath();
	  emit showProfile(segments, radius, pathPoints);
	}
      else if (list[li] == "showthicknessprofile")
	{
	  int searchType = 0;
	  if (list.size()-li > 1)
	    {
	      searchType = qBound(0, list[li+1].toInt(&ok), 1);
	      li++;
	    }
	  int segments = m_paths[idx]->segments();
	  QList< QPair<Vec, Vec> > pathPointNormals = m_paths[idx]->getPointAndNormalPath();
	  emit showThicknessProfile(searchType, segments, pathPointNormals);
	}
      else if (list[li] == "moves")
	{
	  if (list.size()-li > 1)
	    {
	      if (list[li+1] == "-")
		m_paths[idx]->translate(true, false);
	      else
		m_paths[idx]->translate(true, true);

	      li++;
	    }
	  else
	    m_paths[idx]->translate(true, true);
	}
      else if (list[li] == "movet")
	{
	  if (list.size()-li > 1)
	    {
	      if (list[li+1] == "-")
		m_paths[idx]->translate(false, false);
	      else
		m_paths[idx]->translate(false, true);

	      li++;
	    }
	  else
	    m_paths[idx]->translate(false, true);
	}
      else if (list[li] == "extractrawfast" ||  // nearest neighbour interpolationco
	       list[li] == "extractraw") // nearest neighbour interpolationco
	{
	  int rads = m_paths[idx]->getRadX(0);
	  int radt = m_paths[idx]->getRadY(0);

	  int segments = m_paths[idx]->segments();
	  QList<Vec> points = m_paths[idx]->points();
	  QList<Vec> pathPoints = m_paths[idx]->pathPoints();
	  QList<float> pathAngles = m_paths[idx]->pathAngles();

	  if (list[li] == "extractrawfast") // nearest neighbour interpolation
	    emit pathExtractRaw(points,
				pathPoints, pathAngles,
				rads, radt, true);
	  else // linear interpolation
	    emit pathExtractRaw(points,
				pathPoints, pathAngles,
				rads, radt, false);
	}
      else if (list[li] == "extractrawhalfpatchfast" ||
	       list[li] == "extractrawhalfpatch" ||
	       list[li] == "extractrawfullpatchfast" ||
	       list[li] == "extractrawfullpatch")
	{
	  QString keyword = list[li];
	  int rads = m_paths[idx]->getRadX(0);
	  int radt = m_paths[idx]->getRadY(0);
	  int godeep = 10;

	  if (list.size()-li > 1)
	    {
	      godeep = list[li+1].toInt(&ok);
	      godeep = qMax(godeep, 1);
	      li++;
	    }
	  else
	    {
	      bool ok;
	      QString text = QInputDialog::getText(0,
						   "Extract Raw",
						   "Depth value",
						   QLineEdit::Normal,
						   QString("%1").arg(godeep),
						   &ok);
	      if (ok && !text.isEmpty())
		{
		  QStringList gs = text.split(" ", QString::SkipEmptyParts);
		  if (gs.count() >= 1)
		    {
		      godeep = gs[0].toInt();
		    }
		  else
		    {
		      QMessageBox::information(0, "Extract Raw",
			     QString("Expecting one value - got %1").arg(text));
		      return;
		    }
		}
	      else
		return;		  
	    }

	  int segments = m_paths[idx]->segments();
	  QList<Vec> points = m_paths[idx]->points();
	  QList<Vec> pathPoints = m_paths[idx]->pathPoints();
	  QList<float> pathAngles = m_paths[idx]->pathAngles();

	  if (keyword == "extractrawhalfpatchfast")
	    emit patchExtractRaw(points,
				pathPoints, pathAngles,
				rads, radt, true,
				true, godeep);
	  else if (keyword == "extractrawhalfpatch")
	    emit patchExtractRaw(points,
				pathPoints, pathAngles,
				rads, radt, false,
				true, godeep);
	  else if (keyword == "extractrawfullpatchfast")
	    emit patchExtractRaw(points,
				pathPoints, pathAngles,
				rads, radt, true,
				false, godeep);
	  else if (list[li] == "extractrawfullpatch")
	    emit patchExtractRaw(points,
				pathPoints, pathAngles,
				rads, radt, false,
				false, godeep);
	}
      else if (list[li] == "fill")
	{
	  if (Global::useMask())
	    {
	      if (list.size()-li > 2)
		{
		  int rad = list[li+1].toInt(&ok);	  
		  int tag = list[li+2].toInt(&ok);	  
		  QList<Vec> pathPoints = m_paths[idx]->getPointPath();
		  emit fillVolumeAt(pathPoints, rad, tag, true);
		  li+=2;
		}
	      else
		QMessageBox::information(0, "Path Command Error",
					 "tag value not specified");	
	    }
	  else
	    QMessageBox::critical(0, "Error", "Please turn on masks");     
	}
      else if (list[li] == "fillempty")
	{
	  if (Global::useMask())
	    {
	      if (list.size()-li > 2)
		{
		  int rad = list[li+1].toInt(&ok);	  
		  int tag = list[li+2].toInt(&ok);	  
		  QList<Vec> pathPoints = m_paths[idx]->getPointPath();
		  emit fillVolumeAt(pathPoints, rad, tag, false);
		  li+=2;
		}
	      else
		QMessageBox::information(0, "Path Command Error",
					 "tag value not specified");	
	    }
	  else
	    QMessageBox::critical(0, "Error", "Please turn on masks");     
	}
      else if (list[li] == "nocaption")
	{
	  m_paths[idx]->resetCaption();
	  li ++;
	}
      else if (list[li] == "caption")
	{
	  if (list.size()-li > 1 &&
	      list[li+1] == "no")
	    {
	      m_paths[idx]->resetCaption();
	      li ++;
	    }
	  else
	    m_paths[idx]->loadCaption();
	}
      else if (list[li] == "noimage")
	{
	  m_paths[idx]->resetImage();
	  li ++;
	}
      else if (list[li] == "image")
	{
	  if (list.size()-li > 1 &&
	      list[li+1] == "no")
	    {
	      m_paths[idx]->resetImage();
	      li ++;
	    }
	  else
	    m_paths[idx]->loadImage();
	}
      else if (list[li] == "save")
	{
	  QString flnm;
	  flnm = QFileDialog::getSaveFileName(0,
					      "Save path points to text file",
					      Global::previousDirectory(),
					      "Files (*.*)");
	  
	  if (flnm.isEmpty())
	    return;

	  QList<Vec> pts = m_paths[idx]->points();

	  QFile fpath(flnm);
	  fpath.open(QFile::WriteOnly | QFile::Text);
	  QTextStream fd(&fpath);
	  fd << pts.count() << "\n";
	  for(int pi=0; pi < pts.count(); pi++)
	    fd << pts[pi].x << " " << pts[pi].y << " " << pts[pi].z << "\n";
	  
	  fd.flush();
	}
      else
	QMessageBox::information(0, "Path Command Error",
				 QString("Cannot understand the command : ") +
				 cmd);

      li++;
    }
}
